package com.qianxx.viewlibrary.chart.statistical;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
import android.view.View;

import com.qianxx.viewlibrary.R;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * 垂直数据统计面板
 */
public class StatisticalPanel extends View implements Animator.AnimatorListener {
    //画笔
    private Paint paint;
    //柱状条景色
    private int columnarColor = Color.WHITE;
    //柱状条的宽度
    private int columnarWidth = 12;
    //控件宽度
    private int width;
    //控件高度
    private int height;
    //当前进度的百分比
    private double percent;
    //动画持续时间
    private long duration = 1500;
    //最大数值
    private double maxValue;
    //字体颜色
    private int textColor = Color.WHITE;
    //字体大小
    private float textSize = 26;
    //文字与柱状条的间距
    private float textMargin = 45;
    //保留2位小数
    private DecimalFormat decimalFormat = new DecimalFormat("0.00");
    //指示器背景色
    private int indicatorColor = Color.RED;
    //指示器与文字的内边距
    private int indicatorPadding = 15;
    //倒三角的宽度
    private int triangleWidth = 15;
    //倒三角的高度
    private int triangleHeight = 10;
    //数据集
    private List<Double> list = new ArrayList<>();

    public List<Double> getList() {
        return list;
    }

    public void setList(List<Double> list) {
        this.list = list;
        startAnimation();
    }

    public StatisticalPanel(Context context) {
        this(context, null);
    }

    public StatisticalPanel(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public StatisticalPanel(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.StatisticalBar);
        columnarColor = ta.getColor(R.styleable.StatisticalBar_columnar_Color, Color.WHITE);
        columnarWidth = (int) ta.getDimension(R.styleable.StatisticalBar_columnar_Width, 12);
        textSize = ta.getDimension(R.styleable.StatisticalBar_text_Size, 26);
        textColor = ta.getColor(R.styleable.StatisticalBar_text_Color, Color.WHITE);
        indicatorColor = ta.getColor(R.styleable.StatisticalBar_indicator_Color, Color.RED);
        ta.recycle();

        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTextSize(textSize);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = MeasureSpec.getSize(widthMeasureSpec);
        height = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        try {
            //绘制背景柱状条
            drawBackground(canvas);
            //绘制前景柱状条
            drawForeground(canvas);
            //绘制指示器
            drawIndicator(canvas);
            //绘制文字
            drawText(canvas);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 绘制背景柱状条
     *
     * @param canvas
     */
    private void drawBackground(Canvas canvas) {
        paint.setColor(columnarColor);
        paint.setAlpha(80);

        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == null)
                continue;

            float left = (width - columnarWidth * list.size()) / (list.size() + 1) * (i + 1) + columnarWidth * i;
            float top = 0;
            float right = left + columnarWidth;
            float bottom = height;

            RectF background = new RectF();
            background.left = left;
            background.top = top;
            background.right = right;
            background.bottom = bottom;
            canvas.drawRoundRect(background, 45, 45, paint);
        }
    }

    /**
     * 绘制前景柱状条
     *
     * @param canvas
     */
    private void drawForeground(Canvas canvas) {
        paint.setColor(columnarColor);
        paint.setAlpha(255);
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == null)
                continue;

            float left = (width - columnarWidth * list.size()) / (list.size() + 1) * (i + 1) + columnarWidth * i;
            float top = (float) (height - height * list.get(i) / maxValue * percent);
            float right = left + columnarWidth;
            float bottom = height;

            RectF background = new RectF();
            background.left = left;
            background.top = top;
            background.right = right;
            background.bottom = bottom;
            canvas.drawRoundRect(background, 45, 45, paint);
        }
    }

    /**
     * 绘制指示器部分（由圆角矩形和倒三角形组成）
     *
     * @param canvas
     */
    private void drawIndicator(Canvas canvas) {
        paint.setColor(indicatorColor);
        paint.setAlpha(255);

        int i = list.size() % 2 == 0 ? list.size() / 2 - 1 : list.size() / 2;
        String text = "￥" + list.get(i);

        if (list.get(i) == null)
            return;

        float left = (width - columnarWidth * list.size()) / (list.size() + 1) * (i + 1) + columnarWidth * i - getTextWidth(text) / 2 - indicatorPadding;
        float top = (float) (height - height * list.get(i) / maxValue * percent) - getTextHeight(text) - textMargin - indicatorPadding;
        ;
        float right = left + getTextWidth(text) + indicatorPadding * 3;
        float bottom = (float) (height - height * list.get(i) / maxValue * percent) - textMargin + indicatorPadding;

        //绘制圆角矩形部分
        RectF background = new RectF();
        background.left = left;
        background.top = top;
        background.right = right;
        background.bottom = bottom;
        canvas.drawRoundRect(background, 5, 5, paint);

        float x1 = (background.right + background.left) / 2 - triangleWidth;
        float y1 = (float) (height - height * list.get(i) / maxValue * percent) - textMargin + indicatorPadding - 1;
        float x2 = (background.right + background.left) / 2 + triangleWidth;
        float y2 = (float) (height - height * list.get(i) / maxValue * percent) - textMargin + indicatorPadding - 1;
        float x3 = (background.right + background.left) / 2;
        float y3 = (float) (height - height * list.get(i) / maxValue * percent) - textMargin + indicatorPadding + triangleHeight;


        //绘制倒三角形部分
        Path path5 = new Path();
        path5.moveTo(x1, y1);
        path5.lineTo(x2, y2);
        path5.lineTo(x3, y3);
        path5.close();
        canvas.drawPath(path5, paint);
    }

    /**
     * 绘制文字
     *
     * @param canvas
     */
    private void drawText(Canvas canvas) {
        paint.setColor(textColor);
        paint.setAlpha(255);
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == null)
                continue;

            String text = "￥" + twodecimalPlaces(list.get(i) * percent + "");
            float x = (width - columnarWidth * list.size()) / (list.size() + 1) * (i + 1) + columnarWidth * i - getTextWidth(text) / 2;
            float y = (float) (height - height * list.get(i) / maxValue * percent) - textMargin;

            canvas.drawText(text, x, y, paint);
        }
    }

    /**
     * 获取文本的宽度
     *
     * @return
     */
    private int getTextWidth(String text) {
        Rect rect = new Rect();
        paint.setTextSize(textSize);
        paint.getTextBounds(text, 0, text.length(), rect);
        return rect.width();
    }

    /**
     * 获取文本的高度
     *
     * @return
     */
    private int getTextHeight(String text) {
        Rect rect = new Rect();
        paint.setTextSize(textSize);
        paint.getTextBounds(text, 0, text.length(), rect);
        return rect.height();
    }

    /**
     * 设置最大进度值
     *
     * @param maxValue
     */
    public void setMaxValue(double maxValue) {
        this.maxValue = maxValue;
    }


    /**
     * 保留2位小数
     *
     * @param number
     * @return
     */
    public String twodecimalPlaces(String number) {
        return decimalFormat.format(Double.parseDouble(number));
    }

    /**
     * 开始执行动画
     */
    private void startAnimation() {
        setLayerType(LAYER_TYPE_HARDWARE, null);

        ObjectAnimator an = ObjectAnimator.ofFloat(this, "percent", 0, 1);
        an.setInterpolator(new FastOutSlowInInterpolator());
        an.addListener(this);
        an.setDuration(duration);
        an.start();
    }

    public double getPercent() {
        return percent;
    }

    public void setPercent(float percent) {
        this.percent = percent;
        invalidate();
    }

    @Override
    public void onAnimationStart(Animator animation) {

    }

    @Override
    public void onAnimationEnd(Animator animation) {
        setLayerType(LAYER_TYPE_NONE, null);
    }

    @Override
    public void onAnimationCancel(Animator animation) {

    }

    @Override
    public void onAnimationRepeat(Animator animation) {

    }
}
